package common.utils;

import lombok.var;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ListUtil {

    //不可用[方法泛型]进行newArray(),[类泛型]可以
    //newArray()在泛型二次传递的时候丢失为Object
    //会导致java.lang.ClassCastException:
    //[Ljava.lang.Object; cannot be cast to [Ljava.lang.?;
    public static <T> T[] newArray(T... items) {
        return items;
    }

    public static <T> LinkedList<T> newList(T... items) {
        var list = new LinkedList<T>();
        for (var item : items)
            list.add(item);
        return list;
    }

    public static <T> LinkedList<T> create(T... items) {
        return newList(items);
    }

    public static <T> LinkedList<T> createNew(T... items) {
        return create(items);
    }

    public static <T> T[] listToArray(List<T> list, T... array) {
        //这里的array不能用newArray()代替,详情看newArray()注释
        return list.toArray(array);
    }

    public static <T> LinkedList<T> arrayToList(T[] array) {
        var list = new LinkedList<T>();
        for (int index = 0; index < array.length; index++)
            list.add(array[index]);
        return list;
    }

    public static <T> T first(List<T> items) {
        if (items == null || items.size() == 0)
            return null;
        return items.get(0);
    }

    public static <T> List<T> select(List<T> items, int startIndex, int count) {
        var endIndex = startIndex + count;
        if (endIndex > items.size())
            endIndex = items.size();
        if (startIndex > endIndex)
            startIndex = endIndex;
        return items.subList(startIndex, endIndex);
    }

    public static <T> List<T> select(List<T> items, int count) {
        return select(items, 0, count);
    }

    public static <T> T[] select(T[] items, int count) {
        return listToArray(select(arrayToList(items), count));
    }

    public static <T> List<T> combine(List<T> list1, List<T> list2) {
        var list = new ArrayList<T>();
        if (list1 != null)
            list.addAll(list1);
        if (list2 != null)
            list.addAll(list2);
        return list;
    }

    public static <T> LinkedList<String> toStringList(List<T> items) {
        var list = new LinkedList<String>();
        for (var item : items)
            list.add(ConvertUtil.toString(item));
        return list;
    }

    public static <T> LinkedList<String> toStringList(T[] items) {
        return toStringList(arrayToList(items));
    }

    public static <T> String[] toStringArray(List<T> items) {
        var stringArray = new String[items.size()];
        for (var index = 0; index < stringArray.length; index++)
            stringArray[index] = items.get(index).toString();
        return stringArray;
    }

    public static <T> String[] toStringArray(T[] items) {
        return toStringArray(arrayToList(items));
    }

    public static <T> LinkedList<Long> toLongList(List<T> items) {
        var list = new LinkedList<Long>();
        for (var item : items)
            list.add(ConvertUtil.toNullableLong(item));
        return list;
    }

    public static <T> Long[] toLongArray(T[] items) {
        var array = new Long[items.length];
        for (var index = 0; index < items.length; index++)
            array[index] = ConvertUtil.toLong(items[index]);
        return array;
    }

}
